package com.thinkgem.jeesite.modules.book.service;

import com.thinkgem.jeesite.common.persistence.DataEntity;
import com.thinkgem.jeesite.common.persistence.Result;
import com.thinkgem.jeesite.common.service.CrudService;
import com.thinkgem.jeesite.common.utils.IdGen;
import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.modules.book.dao.BookMgrDao;
import com.thinkgem.jeesite.modules.book.dao.BookPurchaseDao;
import com.thinkgem.jeesite.modules.book.dao.BookStoreDao;
import com.thinkgem.jeesite.modules.book.entity.*;
import com.thinkgem.jeesite.modules.sys.entity.User;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 流程模型相关Controller
 *
 * @author ThinkGem
 * @version 2013-11-03
 */
@Service
@Transactional(readOnly = true)
public class BookStoreService extends CrudService<BookStoreDao, BkBookstore>{

    @Autowired
    private BookMgrDao bookMgrDao;

    @Autowired
    private BookPurchaseDao bookPurchaseDao;

    /**
     * 保存数据
     *
     * @param bookstore bookstore
     */
    @Transactional(readOnly = false)
    public void save(BkBookstore bookstore){
        super.save(bookstore);
        UserUtils.removeCache(UserUtils.CACHE_OFFICE_LIST);
    }

    public String getMaxBarCode(){
        return dao.getMaxBarCode();
    }

    public String getMinBarCode(){
        return dao.getMinBarCode();
    }

    /**
     * 根据书籍编号查询藏书信息
     *
     * @param bkId 书籍编号
     * @return 藏书信息
     */
    public List<BkBookstore> getStoresByBkId(String bkId){
        return dao.getStoresByBkId(bkId);
    }

    @Transactional(readOnly = false)
    public void update(BkBookstore bookstore){
        dao.update(bookstore);

    }

    @Transactional(readOnly = false)
    public void insert(BkBookstore bookstore){
        dao.insert(bookstore);
    }

    /**
     * 根据书籍编号增加库存
     *
     * @param bkId      书记编号
     * @param mxArrived 登到数量
     */
    public void addStoreByBkId(String bkId, int mxArrived){
        dao.addStoreByBkId(bkId, mxArrived);
    }

    /**
     * 根据书籍编号减少库存
     *
     * @param bkId      书记编号
     * @param mxArrived 登到数量
     */
    @Transactional(readOnly = false)
    public void reduceStoreByBkId(String bkId, int mxArrived){
        dao.reduceStoreByIsbn(bkId, mxArrived);
    }

    public List<BkBookstore> findPrintDetails(String batchId){
        return dao.findPrintDetails(batchId);
    }

    public void insertBookStores(List<BkBookstore> bookstores){
        dao.insertBookStores(bookstores);

    }

    public void deleteStoreByBatchId(String batchId){
        dao.deleteStoreByBatchId(batchId);
    }

    public BkBookstore findBookStoreByBanid(String banid){
        return dao.findBookStoreByBanid(banid, null);
    }

    @Transactional(readOnly = false)
    public int deleteByBkId(String bkId){
        return dao.deleteByBkId(bkId);
    }

    public BkBookstore getStoreByBkId(String bkId){
        return dao.getStoreByBkId(bkId);
    }

    public String getMaxPlaceCode(String classcode){
        return dao.getMaxPlaceCode(classcode);
    }

    public List<BkBookstore> findStoresByClasscode(String classcode, String place){
        return dao.findStoresByClasscode(classcode, place);
    }

    public List<BkBookstore> getCheckList(String bkId, String batch, String pbdId){
        return dao.getCheckList(bkId, batch, pbdId);
    }

    /**
     * 验收
     *
     * @param store           store
     * @param autoCreateBanId 是否自动生成条码
     */
    @Transactional(rollbackFor = Exception.class, readOnly = false)
    public synchronized void saveStore(BkPurchaseBatchDetail detail, BkBookstore store, String autoCreateBanId) throws Exception{
        // 先保存批次
        detail.preInsert();
        bookPurchaseDao.saveDetail(detail);

        store.setPbdId(detail.getPbdId());
        store.setClasscode(detail.getBkClass());

        String bkId = store.getBkId();
        String batch = store.getBatch();

        int pbdId = store.getPbdId();

        int amount = store.getAmount();
        int booksAmount = store.getBooksAmount();

        User user = UserUtils.getUser();
        String userId = user.getId();
        String loginName = user.getLoginName();

        Timestamp now = new Timestamp(System.currentTimeMillis());

        int peMaxBarCode = 0;
        int barCodeLength = 0;
        String[] banids = null;
        if("1".equals(autoCreateBanId)){

            // 获取 最大的 条码号
            String maxBarCode = this.getMaxBarCodeByUser(loginName);

            maxBarCode = IdGen.getMaxBarCode(maxBarCode);
            barCodeLength = maxBarCode.length();

            // 将后缀转化为数字
            peMaxBarCode = Integer.parseInt(maxBarCode);

            peMaxBarCode--;
        }
        else{
            String banidStrs = store.getBanid();
            banids = banidStrs.split(",");
        }


        String classcode = store.getClasscode();

        BkBookinfo bookinfo = bookMgrDao.get(bkId);
        boolean isBooks = StringUtils.isNotEmpty(bookinfo.getBooks());
        String place = store.getPlace();
        if(place.split("/").length <= 1){
            place = this.createPlace(bkId, classcode, isBooks, "");
        }
        else{
            classcode = place.split("/")[0];
            place = place.split("/")[1];
        }

        // 从编书去库存中的第一本的类型生成索书号
        if(isBooks){
            String temClasscode = getFirstClasscodeByBooks(bookinfo.getBooks());
            classcode = StringUtils.defaultIfEmpty(temClasscode, classcode);
        }

        List<BkBookstore> stores = new ArrayList<>();

        double fristPrice = 0;
        double lastPrice = 0;

        try{
            DecimalFormat df = new DecimalFormat("######0.00");

            String realPriceStr = store.getRealPrice();
            double realPrice = Double.parseDouble(realPriceStr);
            fristPrice = Double.parseDouble(df.format(realPrice / booksAmount));
            // 价格不能被整除
            if((realPrice * 100) % booksAmount != 0){
                lastPrice = realPrice - fristPrice * (booksAmount - 1);
            }else{
                lastPrice = fristPrice;
            }
        }
        catch(Exception e){
            logger.error("图书价格格式错误，不能转化为数字");
        }
        logger.error("图书价格："+fristPrice+"|"+lastPrice);

        for(int i = 0; i < amount * booksAmount; i++){
            BkBookstore temkBookstore = new BkBookstore();
            temkBookstore.preInsert();
            temkBookstore.setBkId(bkId);
            temkBookstore.setClasscode(classcode);

            if("1".equals(autoCreateBanId)){
                IdGen.formatCount = peMaxBarCode;
                String banId = IdGen.getMaxCode(barCodeLength);
                temkBookstore.setBanid(banId);
                peMaxBarCode++;
            }
            else{
                try{
                    String banid = (null == banids) ? "" : banids[i].trim();
                    temkBookstore.setBanid(banid);
                }
                catch(Exception e){
                    temkBookstore.setBanid("");
                }
            }
            // 验证条形码编号是否存在
            BkBookstore bkBookstore = dao.findBookStoreByBanid(temkBookstore.getBanid(), store.getStore());
            if(bkBookstore != null){
                throw new Exception("书库中存在重复的条码号:"+temkBookstore.getBanid()+",请重新设置您的起始条码号！");
            }

            temkBookstore.setStatus(1);
            temkBookstore.setpPrice(String.valueOf(store.getpPrice()));
            if(booksAmount >= 2){
                int temNum = i / amount + 1;
                temkBookstore.setPlace(place + "(" + (temNum) + ")");
                // 图书分多册的时候，并且是最后一本书
                if(temNum == booksAmount){
                    temkBookstore.setpPrice(String.valueOf(lastPrice));
                }
            }
            else{
                temkBookstore.setPlace(String.valueOf(place));
            }

            temkBookstore.setBookname(store.getBookname());
            temkBookstore.setMedia(store.getMedia());
            temkBookstore.setSource(store.getSource());
            temkBookstore.setBinding(store.getBinding());
            temkBookstore.setMsg(store.getMsg());
            temkBookstore.setBatch(batch);
            temkBookstore.setPbdId(pbdId);
            temkBookstore.setStore(store.getStore());
            temkBookstore.setPrice(store.getPrice());
            temkBookstore.settPrice(store.gettPrice());
            temkBookstore.setRealPrice(store.getRealPrice());
            temkBookstore.setTotalCount(1);
            temkBookstore.setLeftCount(1);
            temkBookstore.setIptTme(now);
            temkBookstore.setUserId(userId);

            stores.add(temkBookstore);
        }
        // 只有自动生成的条码时，才更新初始条码表
        if("1".equals(autoCreateBanId)){
            // 修改 用户的起始条码号
            IdGen.formatCount = peMaxBarCode;
            dao.updateBookBanid(IdGen.getMaxCode(barCodeLength), loginName);
        }
        dao.insertBookStores(stores);
    }

    /**
     * 生成索书号
     *
     * @param classcode 分类号
     * @return 索书号
     */
    public String createPlace(String bkId, String classcode, boolean isBooks, String booksNum){
        BkBookstore bookstore = this.getStoreByBkId(bkId);
        // 如果图书馆藏有相同的书，使用相同的索书号
        if(bookstore != null){
            //place = place.split("\\(")[0];
            return bookstore.getPlace();
        }
        else{
            // 获取当前最大的 索书号
            String place = this.getMaxPlaceCode(classcode);
            if(isBooks){
                if(StringUtils.isNotEmpty(booksNum)){
                    String booksPlace = "";
                    // 查询是否有同一系列的书
                    BkBookinfo bookinfo = bookMgrDao.get(bkId);
                    String books = bookinfo.getBooks();
                    if(StringUtils.isNotEmpty(books)){
                        booksPlace = getMaxPlaceCodeByBookId(books);
                    }

                    // 系列的书place 使用v间隔，只有booksNum字段不为空的使用 v表示
                    // 括号的图书是使用一册包含上下册
                    if(StringUtils.isNotEmpty(booksPlace)){
                        String[] booksPlaces;
                        if(booksPlace.contains("v")){
                            booksPlaces = booksPlace.split("v");
                        }
                        else if(booksPlace.contains("(")){
                            booksPlaces = booksPlace.split("\\(");
                        }
                        else{
                            booksPlaces = booksPlace.split(":");
                        }

                        booksPlace = booksPlaces[0] + "v" + booksNum;
                    }
                    else{
                        place = getMaxPlace(place);
                        booksPlace = (Integer.parseInt(place) + 1) + "v" + booksNum;
                    }
                    return booksPlace;
                }
                else{
                    // 查询是否有同一系列的书
                    BkBookinfo bookinfo = bookMgrDao.get(bkId);
                    String books = bookinfo.getBooks();
                    String booksPlace = getMaxPlaceCodeByBookId(books);

                    if(StringUtils.isNotEmpty(booksPlace)){
                        String[] booksPlaces = booksPlace.split(":");

                        if(booksPlaces.length >= 2){
                            booksPlace = booksPlaces[0] + ":" + (Integer.parseInt(booksPlaces[1].split("\\(")[0]) + 1);
                        }
                        else{
                            booksPlace = booksPlaces[0] + ":1";
                        }
                    }
                    else{
                        place = getMaxPlace(place);
                        booksPlace = (Integer.parseInt(place) + 1) + ":1";
                    }
                    return booksPlace;
                }
            }
            else{
                place = getMaxPlace(place);
                return String.valueOf(Integer.parseInt(place) + 1);
            }
        }
    }

    private String getMaxPlace(String place){
        if(StringUtils.isEmpty(place)){
            place = "0";
        }
        else{
            if(place.contains(":")){
                place = place.split(":")[0];
            }
            else if(place.contains("v")){
                place = place.split("v")[0];
            }
            else if(place.contains("(")){
                place = place.split("\\(")[0];
            }
            else{
                place = place.split("\\(")[0];
            }
        }
        return place;
    }

    /**
     * 获取数据库中 丛编最大 的图书索引
     *
     * @param books 丛编名
     * @return place
     */
    private String getMaxPlaceCodeByBookId(String books){
        List<BkBookinfo> booksDetail = bookMgrDao.getByBooks(books);
        String idStr = "";
        for(BkBookinfo item : booksDetail){
            idStr += item.getId() + ",";
        }
        if(idStr.endsWith(",")){
            idStr = idStr.substring(0, idStr.length() - 1);
        }

        String result = "";
        List<String> places = dao.getMaxPlaceCodeByBookId(idStr);
        if(null != places && !places.isEmpty()){
            for(String place : places){
                if(place.contains(":")){
                    result = place;
                    break;
                }
            }
            if(StringUtils.isEmpty(result)){
                result = places.get(0).split("v")[0];
            }
        }
        return result;
    }

    public String getFirstClasscodeByBooks(String books){
        List<BkBookinfo> booksDetail = bookMgrDao.getByBooks(books);
        String idStr = "";
        for(BkBookinfo item : booksDetail){
            idStr += item.getId() + ",";
        }
        if(idStr.endsWith(",")){
            idStr = idStr.substring(0, idStr.length() - 1);
        }
        if(StringUtils.isEmpty(idStr)){
            return "";
        }
        else{
            return dao.getFirstClasscodeByBookId(idStr);
        }
    }

    @Transactional(readOnly = false)
    public int deleteById(String storeId){
        BkBookstore bkBookstore = new BkBookstore();
        bkBookstore.setDelFlag(DataEntity.DEL_FLAG_DELETE);
        bkBookstore.preUpdate();
        bkBookstore.setId(storeId);
        return dao.deleteById(bkBookstore);
    }

    public List<String> checkRepeatBanId(String banIds){
        return dao.checkRepeatBanId(banIds);
    }

    public List<BkBookstore> searchBookstores(String batchNum, String snBegin, String snEnd){
        return dao.searchBookstores(batchNum, snBegin, snEnd);
    }

    public List<ExportBookstore> findExportList(BkBookstore bkBookstore){
        return dao.findExportList(bkBookstore);
    }

    public List<BkBookstore> getPurchaseLedger(String begin, String end, String batchId, int number){
        return dao.getPurchaseLedger(begin, end, batchId, number);
    }
    public List<BkBookstore> searchBookstoresByIds(String storeIds){
        return dao.searchBookstoresByIds(storeIds);
    }
    public List<GeneralLedger> getGeneralLedger(String begin, String end, String batchNumber){
        return dao.getGeneralLedger(begin, end, batchNumber);
    }

    public String getClasscodeByBkIdsStr(String bkIds){
        return dao.getClasscodeByBkIdsStr(bkIds);
    }

    public boolean checkRepeatBanIdById(String storeId, String banId){
        return dao.checkRepeatBanIdById(storeId, banId) >= 1;
    }

    public BkBookstore getById(String id){
        return dao.getById(id);
    }

    @Transactional(readOnly = false)
    public int updateStore(BkBookstore saveBkStore){
        return dao.updateStore(saveBkStore);
    }

    public Map<String, String> getPurchaseLedgerAmount(String begin, String end, String batchId){
        return dao.getPurchaseLedgerAmount( begin, end, batchId);
    }

    public List<BkBookBan> getBookBanList(){
        return dao.getBookBanList();
    }

    public String myLastBanId(String loginName){
        return dao.myLastBanId(loginName);
    }

    @Transactional(readOnly = false)
    public Result batchChangePlace(List<BkBookstore> placeList){
        for(BkBookstore bookstore:placeList){
            dao.changePlace(bookstore.getId(), bookstore.getClasscode(), bookstore.getPlace());
        }
        return new Result("成功");
    }

    @Transactional(readOnly = false)
    public Result deleteStoreByStoreIds(String storeIds){
        dao.deleteStoreByStoreIds(storeIds);
        return new Result("成功");
    }

    // 获取 最大的 条码号
    public String getMaxBarCodeByUser(String loginName){
        return dao.getMaxBarCodeByUser(loginName);
    }

    @Transactional(readOnly = false)
    public Result setBookShelf(String shelfId, String setSerNumnber, String setTypeValue){
        int result = 0;
        //判断是否使用ISBN方式进行上架
        if("1".equals(setTypeValue)){
            BkBookstore bkBookstore = new BkBookstore();
            bkBookstore.setIsbn(setSerNumnber);
            //ISBN没有存储在bkstore表中，只能关联bookinfo表查询isbn信息
            List<BkBookstore> bkBookstoreList = dao.findList(bkBookstore);
            if (bkBookstoreList != null && !bkBookstoreList.isEmpty() ) {
                for(BkBookstore bookstore:bkBookstoreList){
                    result = dao.setBookShelfByIsbn(shelfId, bookstore.getId());
                }
            }else {
                return new Result(Result.FAILURE, "上架失败，没查询到该ISBN的图书信息!", null);
            }
        } else {
            result = dao.setBookShelfByBanid(shelfId, setSerNumnber);
        }

        if(result > 0 && StringUtils.isNotEmpty(shelfId)){
            return new Result("上架成功!");
        }
        else if(result > 0 && StringUtils.isEmpty(shelfId)){
            return new Result("删除书架信息成功!");
        }
        else{
            return new Result(Result.FAILURE, "上架失败,请检查这本图书!", null);
        }
    }
}